const { Tenant } = require('../models');

// 租户识别中间件 - 通过域名或租户ID识别租户
const identifyTenant = async (request, reply) => {
  try {
    let tenant = null;
    
    // 方法1: 通过 X-Tenant-ID 头部识别
    const tenantIdHeader = request.headers['x-tenant-id'];
    if (tenantIdHeader) {
      tenant = await Tenant.findByTenantId(tenantIdHeader);
    }
    
    // 方法2: 通过子域名识别
    if (!tenant) {
      const host = request.headers.host;
      if (host) {
        const subdomain = host.split('.')[0];
        if (subdomain && subdomain !== 'www' && subdomain !== 'api') {
          tenant = await Tenant.findByDomain(subdomain);
        }
      }
    }
    
    // 方法3: 通过查询参数识别
    if (!tenant && request.query.tenant) {
      tenant = await Tenant.findByTenantId(request.query.tenant) || 
               await Tenant.findByDomain(request.query.tenant);
    }
    
    // 方法4: 通过请求体识别（POST/PUT 请求）
    if (!tenant && request.body && request.body.tenantId) {
      tenant = await Tenant.findByTenantId(request.body.tenantId);
    }
    
    if (tenant) {
      // 检查租户状态
      if (tenant.status !== 'active') {
        return reply.code(403).send({
          error: 'Tenant Unavailable',
          message: `Tenant is ${tenant.status}`,
          tenantId: tenant.tenantId
        });
      }
      
      // 检查订阅状态
      if (tenant.isSubscriptionExpired) {
        return reply.code(402).send({
          error: 'Subscription Expired',
          message: 'Tenant subscription has expired',
          tenantId: tenant.tenantId,
          expiredDate: tenant.subscription.endDate
        });
      }
      
      // 将租户信息添加到请求对象
      request.tenant = {
        id: tenant._id.toString(),
        tenantId: tenant.tenantId,
        name: tenant.name,
        domain: tenant.domain,
        plan: tenant.plan,
        settings: tenant.settings,
        limits: tenant.settings.limits
      };
      
      request.log.info(`Tenant identified: ${tenant.tenantId} (${tenant.name})`);
    }
    
  } catch (error) {
    request.log.error('Tenant identification error:', error);
    return reply.code(500).send({
      error: 'Internal Server Error',
      message: 'Failed to identify tenant'
    });
  }
};

// 强制要求租户识别的中间件
const requireTenant = async (request, reply) => {
  if (!request.tenant) {
    return reply.code(400).send({
      error: 'Tenant Required',
      message: 'Tenant identification is required for this operation'
    });
  }
};

// 租户数据隔离中间件
const enforceTenantIsolation = async (request, reply) => {
  if (!request.tenant) {
    return reply.code(400).send({
      error: 'Tenant Required',
      message: 'Tenant context is required'
    });
  }
  
  // 自动为查询添加租户过滤条件
  if (!request.query) {
    request.query = {};
  }
  request.query.tenantId = request.tenant.tenantId;
  
  // 自动为请求体添加租户ID
  if (request.body && typeof request.body === 'object') {
    request.body.tenantId = request.tenant.tenantId;
  }
  
  // 添加租户上下文到请求对象
  request.tenantContext = {
    tenantId: request.tenant.tenantId,
    limits: request.tenant.limits,
    features: request.tenant.settings.features
  };
};

// 功能检查中间件
const requireFeature = (featureName) => {
  return async (request, reply) => {
    if (!request.tenant) {
      return reply.code(400).send({
        error: 'Tenant Required',
        message: 'Tenant context is required'
      });
    }
    
    const hasFeature = request.tenant.settings.features.get(featureName);
    
    if (!hasFeature) {
      return reply.code(403).send({
        error: 'Feature Not Available',
        message: `Feature '${featureName}' is not available for this tenant`,
        tenantId: request.tenant.tenantId,
        plan: request.tenant.plan
      });
    }
  };
};

// 使用限制检查中间件
const checkUsageLimit = (limitType) => {
  return async (request, reply) => {
    if (!request.tenant) {
      return reply.code(400).send({
        error: 'Tenant Required',
        message: 'Tenant context is required'
      });
    }
    
    const limit = request.tenant.limits[limitType];
    if (!limit) {
      return; // 没有设置限制，允许继续
    }
    
    // 这里需要根据具体的限制类型来检查当前使用量
    // 例如：用户数量、存储空间、API 调用次数等
    let currentUsage = 0;
    
    switch (limitType) {
      case 'users':
        const { User } = require('../models');
        currentUsage = await User.countDocuments({ tenantId: request.tenant.tenantId });
        break;
      case 'apiCalls':
        // 这里应该从缓存或数据库中获取当前 API 调用次数
        // 暂时跳过检查
        return;
      case 'storage':
        // 这里应该计算当前存储使用量
        // 暂时跳过检查
        return;
      default:
        return;
    }
    
    if (currentUsage >= limit) {
      return reply.code(429).send({
        error: 'Usage Limit Exceeded',
        message: `${limitType} limit exceeded`,
        tenantId: request.tenant.tenantId,
        limit: limit,
        currentUsage: currentUsage
      });
    }
    
    // 将使用情况添加到请求对象
    request.usage = request.usage || {};
    request.usage[limitType] = {
      current: currentUsage,
      limit: limit,
      remaining: limit - currentUsage
    };
  };
};

// 租户计划检查中间件
const requirePlan = (requiredPlans) => {
  return async (request, reply) => {
    if (!request.tenant) {
      return reply.code(400).send({
        error: 'Tenant Required',
        message: 'Tenant context is required'
      });
    }
    
    const plans = Array.isArray(requiredPlans) ? requiredPlans : [requiredPlans];
    
    if (!plans.includes(request.tenant.plan)) {
      return reply.code(403).send({
        error: 'Plan Upgrade Required',
        message: `This feature requires one of the following plans: ${plans.join(', ')}`,
        tenantId: request.tenant.tenantId,
        currentPlan: request.tenant.plan,
        requiredPlans: plans
      });
    }
  };
};

// 租户域名验证中间件
const validateTenantDomain = async (request, reply) => {
  if (!request.tenant) {
    return;
  }
  
  const host = request.headers.host;
  if (!host) {
    return;
  }
  
  // 检查是否使用了正确的域名
  const subdomain = host.split('.')[0];
  
  if (subdomain !== request.tenant.domain && 
      subdomain !== 'api' && 
      subdomain !== 'www') {
    
    request.log.warn(`Domain mismatch: expected ${request.tenant.domain}, got ${subdomain}`);
    
    // 可以选择重定向到正确的域名或返回错误
    // 这里选择记录警告但继续处理
  }
};

// 租户活动记录中间件
const logTenantActivity = async (request, reply) => {
  if (!request.tenant) {
    return;
  }
  
  // 记录租户活动（可以用于分析和计费）
  const activity = {
    tenantId: request.tenant.tenantId,
    method: request.method,
    url: request.url,
    userAgent: request.headers['user-agent'],
    ip: request.ip,
    timestamp: new Date()
  };
  
  // 这里可以将活动记录到数据库或日志系统
  request.log.info('Tenant activity:', activity);
  
  // 可以在这里实现 API 调用计数
  // await incrementApiCallCount(request.tenant.tenantId);
};

module.exports = {
  identifyTenant,
  requireTenant,
  enforceTenantIsolation,
  requireFeature,
  checkUsageLimit,
  requirePlan,
  validateTenantDomain,
  logTenantActivity
};